package com.xpalive.attach.aspect;

import com.xpalive.base.dto.result.RespResult;
import com.xpalive.utils.XCommonUtils;
import com.xpalive.attach.dto.Attachment;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;

/**
 * @auther xiongping
 * @date 2019/6/4
 */
@Aspect
@Configuration
@Slf4j
public class AttachResultAspect {

    private static final String ANNO = "@AttachResultEnable";
    private static final String ANNO_INTERFACE = "AttachResult";


    @Pointcut("@annotation(com.xpalive.attach.aspect.AttachResultEnable)")
    public void annotationPointCut() {
    }

    @AfterReturning(value = "annotationPointCut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        AttachResultEnable action = method.getAnnotation(AttachResultEnable.class);
        if (action.active()) {
            Assert.notNull(result, MessageFormat.format("使用{0}注解标注的方法需要有返回值", ANNO));
            Long id;
            String msg = MessageFormat.format("使用{0}注解标注的方法返回值必须是{1}的子类", ANNO, ANNO_INTERFACE);
            if (result instanceof RespResult) {
                Object resultObject = ((RespResult) result).getData();
                Assert.isTrue(resultObject instanceof AttachResult, msg);
                id = XCommonUtils.getId((AttachResult) resultObject);
            } else {
                Assert.isTrue(result instanceof AttachResult, msg);
                id = XCommonUtils.getId((AttachResult) result);
            }

            String[] value = action.value();
            List<String> refTypeList = new ArrayList<>();
            if (value != null) {
                refTypeList = Arrays.asList(value);
            }
            // findById and filter By RefTypeList if refTypeList is not null
            List<Attachment> attachmentList = new ArrayList<>();

            if (result instanceof RespResult) {
                AttachResult resultObject = (AttachResult) ((RespResult) result).getData();
                Assert.isTrue(resultObject instanceof AttachResult, msg);
                resultObject.setAttachmentList(attachmentList);
            } else {
                Assert.isTrue(result instanceof AttachResult, msg);
                ((AttachResult) result).setAttachmentList(attachmentList);
            }

        } else {
            log.info("{} active is false", ANNO);
        }
    }

}
